package com.boot.utils;

import com.boot.constant.Constants;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * 微信统一下单接口
 */
public class CreateUnifiedOrder {

    /**
     * 统一下单接口
     * @param request
     * @param map
     * @return
     */
    public static String UnifiedOrder(HttpServletRequest request, Map<String,Object> map) {

        // 创建条件
        double price=Double.parseDouble(map.get("totalPrice").toString());
        String outTradeNo=map.get("outTradeNo").toString();
        String tradeType=map.get("tradeType").toString();
        String openId=null;
        if(!tradeType.equals("APP")){
            openId =map.get("openId").toString();
        }

        String notifyUrl=map.get("notifyUrl").toString();
        String wxPayAppId=map.get("wxPayAppId").toString();

        // 接受参数(金额)
        double mo = (Double.parseDouble(String.format("%.2f", price))) * 100;
        String amountFen = String.valueOf((int) mo);
        System.err.println("小数:" + mo);
        // 接受参数(openid)
        // 接口调用总金额单位为分换算一下(测试金额改成1,单位为分则是0.01,根据自己业务场景判断是转换成float类型还是int类型)
        // Integer.valueOf(((int)(mo))).toString();
        // 创建hashmap(用户获得签名)
        SortedMap<String, String> paraMap = new TreeMap<>();
        // 设置body变量 (支付成功显示在微信支付 商品详情中)
        String body = "蜜蜂嗡嗡商城";
        // 设置随机字符串
        String nonceStr = Units.getRandomStringByLength(32);
        // 设置请求参数(小程序ID)
        paraMap.put("appid", wxPayAppId);
        // 设置请求参数(商户号)
        paraMap.put("mch_id", Constants.wxspMch_id);
        // 设置请求参数(随机字符串)
        paraMap.put("nonce_str", nonceStr);
        // 设置请求参数(商品描述)
        paraMap.put("body", body);
        // 设置请求参数(商户订单号)
        paraMap.put("out_trade_no",outTradeNo);
        // 设置请求参数(总金额)
        paraMap.put("total_fee", amountFen);
        // 设置请求参数(终端IP)
        // 获取请求ip地址
        String ip = Units.getRemoteHost(request);
        paraMap.put("spbill_create_ip", ip);
        // 设置请求参数(通知地址)
        paraMap.put("notify_url", notifyUrl);
        // 设置请求参数(交易类型)
        paraMap.put("trade_type", tradeType);
        // 设置请求参数(openid)(在接口文档中 该参数 是否必填项 但是一定要注意 如果交易类型设置成'JSAPI'则必须传入openid)
        if(!tradeType.equals("APP")){
            paraMap.put("openid",openId);
        }

        // 调用逻辑传入参数按照字段名的 ASCII 码从小到大排序（字典序）
        String stringA = Units.formatUrlMap(paraMap, false, false);
        // 第二步，在stringA最后拼接上key得到stringSignTemp字符串，并对stringSignTemp进行MD5运算，再将得到的字符串所有字符转换为大写，得到sign值signValue。(签名)
        String sign = null;
        try {
            sign = PayUtil.WXMD5(stringA + "&key=" + Constants.KEY).toUpperCase();
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        System.err.println("签名00000" + sign);
        // 将参数 编写XML格式
        StringBuffer paramBuffer = new StringBuffer();
        paramBuffer.append("<xml>");
        paramBuffer.append("<appid>" + wxPayAppId + "</appid>");
        paramBuffer.append("<body>" + body + "</body>");
        paramBuffer.append("<mch_id>" + Constants.wxspMch_id + "</mch_id>");
        paramBuffer.append("<nonce_str>" + paraMap.get("nonce_str") + "</nonce_str>");
        paramBuffer.append("<notify_url>" + paraMap.get("notify_url") + "</notify_url>");
        if(!tradeType.equals("APP")){
            paramBuffer.append("<openid>" + paraMap.get("openid") + "</openid>");
        }
        paramBuffer.append("<out_trade_no>" + paraMap.get("out_trade_no") + "</out_trade_no>");
        paramBuffer.append("<spbill_create_ip>" + paraMap.get("spbill_create_ip") + "</spbill_create_ip>");
        paramBuffer.append("<total_fee>" + paraMap.get("total_fee") + "</total_fee>");
        paramBuffer.append("<trade_type>" + paraMap.get("trade_type") + "</trade_type>");
        paramBuffer.append("<sign>" + sign + "</sign>");
        paramBuffer.append("</xml>");

        return paramBuffer.toString();
    }

    /**
     * 生成 微信支付 签名后台
     * @param prepayId
     * @return
     */
    public static JSONObject generateSignature(String prepayId,String wxPayAppId) {

        //实例化返回对象
        JSONObject resultJson = new JSONObject();

        //获得参数(微信统一下单接口生成的prepay_id )
        /* String prepayId = request.getParameter("prepayId");*/
        System.err.println("prepayId,"+prepayId);
        //创建 时间戳
        String timeStamp = Units.DateToTimestamp(new Date()); //Long.valueOf(System.currentTimeMillis()).toString();
        //创建 随机串
        String nonceStr = Units.getRandomStringByLength(32).replaceAll("-", "").toUpperCase();
        //创建 MD5
        String signType = "MD5";

        //创建hashmap(用户获得签名)
        SortedMap<String, String> paraMap = new TreeMap();
        //设置(小程序ID)(这块一定要是大写)

        if(wxPayAppId.equals("wx7ec6f11aac462c6e")){
            paraMap.put("appid", wxPayAppId);
            paraMap.put("partnerid", Constants.wxspMch_id);
            paraMap.put("prepayid", prepayId);
            paraMap.put("package", "Sign=WXPay");
            paraMap.put("noncestr", nonceStr);
            paraMap.put("timestamp", timeStamp);
//            paraMap.put("appid", "wx7ec6f11aac462c6e");
//            paraMap.put("partnerid", "1610836517");
//            paraMap.put("prepayid", "wx10091513227317d17b268381caf8ee0000");
//            paraMap.put("package", "Sign=WXPay");
//            paraMap.put("noncestr", "8X0MFINMIT0Y0MVIKIATQS2OW3ZIYDJF");
//            paraMap.put("timestamp", "1636506913");
        }else{
            paraMap.put("appId",wxPayAppId);
            //设置(时间戳)
            paraMap.put("timeStamp",timeStamp);
            //设置(随机串)
            paraMap.put("nonceStr", nonceStr);
            //设置(数据包)
            paraMap.put("package", "prepay_id="+prepayId);
            //设置(签名方式)
            paraMap.put("signType", signType);
        }
        //调用逻辑传入参数按照字段名的 ASCII 码从小到大排序（字典序）
        String stringA =Units.formatUrlMap(paraMap, false, false);
        //第二步，在stringA最后拼接上key得到stringSignTemp字符串，并对stringSignTemp进行MD5运算，再将得到的字符串所有字符转换为大写，得到sign值signValue。(签名)
        String sign=null;
        try {
            System.err.println("签名字符串:"+stringA);
            sign = PayUtil.WXMD5(stringA+"&key="+Constants.KEY).toUpperCase();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if(StringUtils.isNotBlank(sign)){
            System.err.println("sign==111111111===>:"+sign);
            //返回appid
            resultJson.put("appId", wxPayAppId);
            //返回商户
            resultJson.put("partnerId", Constants.wxspMch_id);
            //返回签名信息
            resultJson.put("sign", sign);
            //返回随机串(这个随机串是新创建的)
            resultJson.put("nonceStr", nonceStr);
            //返回时间戳
            resultJson.put("timeStamp", timeStamp);
            //返回数据包
            resultJson.put("package", "prepay_id="+prepayId);
            System.err.println("微信 支付接口生成签名 设置返回值");
        }
        System.err.println("微信 支付接口生成签名 方法结束"+sign);
        return resultJson;
    }


    /**
     * 查看物流信息
     * @param expNo
     * @return
     * @throws Exception
     */
    public static String getWuliu(String expNo)throws Exception{
        String path = "/kdi";
        System.out.println("请先替换成自己的AppCode");
        String AppCode = Constants.AppCode;  // !!!替换填写自己的AppCode 在买家中心查看
        String urlSend = Constants.ReqURL + path + "?no=" + expNo.replaceAll("\\s*", "");
        URL url = new URL(urlSend);
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
        httpURLConnection.setRequestProperty("Authorization", "APPCODE " + AppCode);//格式Authorization:APPCODE (中间是英文空格)
        //int httpCode = httpURLConnection.getResponseCode();
        String json = Units.read(httpURLConnection.getInputStream());
        //System.out.println("/* 获取服务器响应状态码 200 正常；400 权限错误 ； 403 次数用完； */ ");
        //System.out.println(httpCode);
        System.out.print(json);
        return json;
    }

}
